<template>
  <div id="map" style="height: 100vh;"></div>
  <div style="position: absolute; top: 10px; right: 10px; z-index: 1000;">
    <button @click="switchMode">切换 OFFBOARD</button>
    <button @click="arm">解锁</button>
    <button @click="takeoff">起飞</button>
    <button @click="land">降落</button>
    <button @click="disarm">上锁</button>
    <button @click="clearTarget">清除目标</button>
  </div>
</template>

<script>
import L from 'leaflet'
import { onMounted } from 'vue'
import ROSConnection from '../utils/ROSConnection'
import FlightModeCommand from '../utils/FlightModeCommand'

export default {
  setup() {
    let map = null
    let targetMarker = null
    let uavMarker = null
    let lastUavPos = null
    const DEFAULT_ALT = 20.0

    const switchMode = () => FlightModeCommand.sendFlightMode(6)
    const arm = () => FlightModeCommand.arm()
    const disarm = () => FlightModeCommand.disarm()
    const takeoff = () => FlightModeCommand.takeoff(DEFAULT_ALT)
    const land = () => FlightModeCommand.land()
    const clearTarget = () => {
      if (targetMarker) {
        map.removeLayer(targetMarker)
        targetMarker = null
      }
    }

    function computeDistance(lat1, lon1, lat2, lon2) {
      const R = 6371000
      const dLat = (lat2 - lat1) * Math.PI / 180
      const dLon = (lon2 - lon1) * Math.PI / 180
      const a = Math.sin(dLat/2) ** 2 +
                Math.cos(lat1 * Math.PI/180) * Math.cos(lat2 * Math.PI/180) *
                Math.sin(dLon/2) ** 2
      const c = 2 * Math.atan2(Math.sqrt(a), Math.sqrt(1-a))
      return R * c
    }

    const sendGoto = (lat, lon) => {
      FlightModeCommand.goto(lat, lon, DEFAULT_ALT)

      let popupText = '目标点'
      if (lastUavPos) {
        const dist = computeDistance(lat, lon, lastUavPos.lat, lastUavPos.lon)
        popupText += `\\n距离 UAV：${dist.toFixed(1)} 米`
      }

      if (targetMarker) {
        targetMarker.setLatLng([lat, lon]).bindPopup(popupText).openPopup()
      } else {
        targetMarker = L.marker([lat, lon], { title: '目标点' })
          .addTo(map)
          .bindPopup(popupText)
          .openPopup()
      }
    }

    onMounted(() => {
      map = L.map('map').setView([0, 0], 3)
      L.tileLayer('https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png', {
        maxZoom: 19
      }).addTo(map)

      map.on('click', function (e) {
        const lat = e.latlng.lat
        const lon = e.latlng.lng
        sendGoto(lat, lon)
      })

      ROSConnection.connect((id, pos) => {
        if (id === 'uav1') {
          lastUavPos = pos
          if (uavMarker) {
            uavMarker.setLatLng([pos.lat, pos.lon])
          } else {
            uavMarker = L.marker([pos.lat, pos.lon], { title: 'UAV' }).addTo(map)
          }

          map.panTo([pos.lat, pos.lon])

          if (targetMarker) {
            const dist = computeDistance(targetMarker.getLatLng().lat, targetMarker.getLatLng().lng, pos.lat, pos.lon)
            targetMarker.setPopupContent(`目标点\\n距离 UAV：${dist.toFixed(1)} 米`)
          }
        }
      })

      FlightModeCommand.init(ROSConnection.getROS())
    })

    return {
      switchMode, arm, disarm, takeoff, land, clearTarget
    }
  }
}
</script>
